from index.basic_db_ops import get_bs_virtual_scene
from index.basic_db_ops2 import get_scene_user_element, get_scene_bs_element, count_scene_user_element
from index.ConvexProject.convex_optimization.system_initialization import *
from index.ConvexProject.convex_optimization.userassociation_main import userassociation_energysharing_once
from index.ConvexProject.parameter import const
from typing import List

def pos_bs_element(Session):
    """
    获取所有的基站位置信息
    :param Session:
    :return: bs_list, bs_number;
    """
    bs_list = []
    bs_number = get_bs_virtual_scene(Session, 1, "bs_number")
    print("现在基站的数量是:", bs_number)
    for bs_id in range(1, bs_number + 1, 1):
        # 生成字典元素
        bs_element = dict()
        bs_element["X"] = round_num(get_scene_bs_element(Session, bs_id, "lon"))
        bs_element["Y"] = round_num(get_scene_bs_element(Session, bs_id, "lat"))
        bs_list.append(bs_element)
    return bs_list, bs_number


def pos_user_element(Session, time_id):
    """
    获取所有的用户位置信息
    :param Session:
    :param time_id:
    :return: 返回列表，包含所有位置信息
    """
    user_list = []
    user_number = count_scene_user_element(Session, time_id)
    print(f"现在{time_id}时刻用户的数量是:{user_number}")
    for time_userrank in range(1, user_number + 1, 1):
        # 生成字典元素
        user_element = dict()
        user_element["X"] = get_scene_user_element(Session, "lon", time_id, time_userrank)
        user_element["Y"] = get_scene_user_element(Session, "lat", time_id, time_userrank)
        user_list.append(user_element)
    return user_list, user_number


# 对于列表当中的元素进行精度限制
def round_list_or_matrix(data):
    """
    对列表或矩阵（嵌套列表）中的浮点数进行精度限制，保留小数点后两位。
    :param data: 输入的列表或矩阵（嵌套列表），元素可以是浮点数或包含浮点数的列表
    :return: 处理后的列表或矩阵，其中的浮点数已保留两位小数
    """
    if isinstance(data, list):
        if all(isinstance(x, float) for x in data):  # 处理普通列表
            return [round(num, 2) for num in data]
        else:  # 处理矩阵（嵌套列表）
            return [[round(num, 2) for num in row] for row in data]
    else:
        raise TypeError("输入的数据必须是列表或嵌套列表")


def round_num(num):
    return round(num, 2)


# 用于修改常量模块当中的量，这样就可以实现一个函数解决问题
def set_constPara(bs_num, user_level, power_macro, power_micro: List, band_macro, band_micro: List):
    # 与bs_num相关的部分
    const.modify_const("BS_NUM", bs_num)
    const.modify_const("RB_MAX", get_RB_MAX(bs_num))
    const.modify_const("RB_W", get_RB_W(bs_num))
    const.modify_const("P_WORK", get_P_WORK(bs_num))
    const.modify_const("P_SLEEP", get_P_SLEEP(bs_num))
    const.modify_const("ONE_BS", get_ONE_BS(bs_num))
    const.modify_const("ZERO_BS", get_ZERO_BS(bs_num))

def set_constPara2(bs_num, user_level, power_macro, power_micro: List, band_macro, band_micro: List):
    # 与bs_num相关的部分
    import numpy as np

    # 区域常量
    # 仿真区域边长，单位为米，代表一个 1km * 1km 的正方形区域
    L = 1000

    # 路径参数
    # 路径衰减系数，用于描述信号在传播过程中的衰减程度
    ALPHA = 2.5
    # 白噪声功率，在信号接收时会产生的背景噪声功率
    NOISE = 3e-09

    # 用户参数
    # 用户信噪比要求上限，单位为 dB，用户可接受的最大信噪比
    SINR_MAX = 40
    # 用户信噪比要求下限，单位为 dB，用户正常通信所需的最小信噪比
    SINR_MIN = 20

    # 网络常数
    # 基站的总数量
    BS_NUM = bs_num
    # 每个时刻对应的用户数量基础值列表，可用于模拟不同时刻的用户数量变化
    UE_NUM_BASE = [10, 7, 4, 3, 2, 2, 3, 4, 6, 8, 9, 10, 10, 11, 11, 13, 13, 13, 14, 15, 16, 16, 15, 13]
    # 将基础用户数量乘以 3，得到潮汐用户数列表，模拟不同时刻的用户数量变化
    UE_NUM_SEQUENCE = [i * user_level for i in UE_NUM_BASE]

    # 网络参数
    # 功放效率，即功率放大器将输入功率转换为输出功率的效率
    ETA = 0.16
    # 宏基站在工作状态下的静态功率，不随发射功率变化的固定功率消耗
    P_STATIC_WORK_MACRO = 800
    # 微基站在工作状态下的静态功率，不随发射功率变化的固定功率消耗
    P_STATIC_WORK_MICRO = 200
    # 宏基站在休眠状态下的静态功率，休眠时的固定功率消耗
    P_STATIC_SLEEP_MACRO = 100
    # 微基站在休眠状态下的静态功率，休眠时的固定功率消耗
    P_STATIC_SLEEP_MICRO = 50

    # 宏基站的最大发射功率，单位为瓦
    P_MAX_MACRO = power_macro
    # 微基站的最大发射功率，单位为瓦
    P_MAX_MICRO = 40
    P_MAX_MICRO_list = power_micro

    # 宏基站的最大功耗，包括发射功率和静态工作功率
    P_BS_MAX_MACRO = P_MAX_MACRO / ETA + P_STATIC_WORK_MACRO
    # 微基站的最大功耗，包括发射功率和静态工作功率
    P_BS_MAX_MICRO = P_MAX_MICRO / ETA + P_STATIC_WORK_MICRO

    # 每个资源块分配的发射功率，单位为瓦
    RB_PR = 0.5
    # 宏基站总共的资源块数量
    RB_MAX_MACRO = P_MAX_MACRO / RB_PR
    # 微基站总共的资源块数量
    RB_MAX_MICRO = P_MAX_MICRO / RB_PR
    # 一个形状为 [1, BS_NUM] 的数组，用于存储每个基站的最大资源块数
    RB_MAX = np.ones(shape=[1, BS_NUM])
    # 先将所有基站的最大资源块数初始化为微基站的最大资源块数
    RB_MAX[:, :] = RB_MAX_MICRO
    # 将第一个基站（假设为宏基站）的最大资源块数设置为宏基站的最大资源块数
    RB_MAX[0, 0] = RB_MAX_MACRO

    # 宏基站的总带宽，单位为赫兹 20M
    W_MAX_MACRO = 20000000
    # 微基站的总带宽，单位为赫兹 5M
    W_MAX_MICRO = 5000000
    # 宏基站每个资源块的带宽，单位为赫兹
    RB_W_MACRO = W_MAX_MACRO / RB_MAX_MACRO
    # 微基站每个资源块的带宽，单位为赫兹
    RB_W_MICRO = W_MAX_MICRO / RB_MAX_MICRO
    # 一个形状为 [1, BS_NUM] 的数组，用于存储每个基站的资源块带宽
    RB_W = np.zeros(shape=[1, BS_NUM])
    # 先将所有基站的资源块带宽初始化为微基站的资源块带宽
    RB_W[:, :] = RB_W_MICRO
    # 将第一个基站（假设为宏基站）的资源块带宽设置为宏基站的资源块带宽
    RB_W[0, 0] = RB_W_MACRO

    # 其他网络参数
    # 一个形状为 [1, BS_NUM] 的数组，用于存储每个基站的工作功率
    P_WORK = np.ones(shape=[1, BS_NUM])
    # 先将所有基站的工作功率初始化为微基站的工作静态功率
    P_WORK[:, :] = P_STATIC_WORK_MICRO
    # 将第一个基站（假设为宏基站）的工作功率设置为宏基站的工作静态功率
    P_WORK[0, 0] = P_STATIC_WORK_MACRO
    # 一个形状为 [1, BS_NUM] 的数组，用于存储每个基站的休眠功率
    P_SLEEP = np.ones(shape=[1, BS_NUM])
    # 先将所有基站的休眠功率初始化为微基站的休眠静态功率
    P_SLEEP[:, :] = P_STATIC_SLEEP_MICRO
    # 将第一个基站（假设为宏基站）的休眠功率设置为宏基站的休眠静态功率
    P_SLEEP[0, 0] = P_STATIC_SLEEP_MACRO
    # 一个形状为 [1, BS_NUM] 的全 1 数组，可用于一些计算中的辅助操作
    ONE_BS = np.ones(shape=[1, BS_NUM])
    # 一个形状为 [1, BS_NUM] 的全 0 数组，可用于一些计算中的辅助操作
    ZERO_BS = np.zeros(shape=[1, BS_NUM])

    # 电池参数
    # 电池的放电下限
    BATTERY_MIN = 100
    # 电池的充电上限
    BATTERY_MAX = 2000
    # 电池的充放电效率，即充电和放电过程中的能量转换效率
    ETA_BATTERY = 0.9

    # 其他参数
    # 传统能源的碳排放因子，单位电量产生的碳排放量
    ETA_GRID = 8e-04
    # 光伏能源的碳排放因子，单位电量产生的碳排放量
    ETA_PV = 1e-04

    # 要求
    # 光伏利用率要求，即实际利用的光伏电量占总光伏发电量的比例
    PV_REQ = 1.0


# get类型函数为按照基站数量生成需要的用于计算的矩阵
def get_RB_MAX(bs_num):
    RB_MAX = np.ones(shape=[1, bs_num])  # 最大资源块数 与基站数量有关
    RB_MAX[:, :] = const.RB_MAX_MICRO
    RB_MAX[0, 0] = const.RB_MAX_MACRO
    return RB_MAX

def get_RB_W(bs_num):
    RB_W = np.ones(shape=[1, bs_num])  # 最大资源块数 与基站数量有关
    RB_W[:, :] = const.RB_MAX_MICRO
    RB_W[0, 0] = const.RB_MAX_MACRO
    return  RB_W

def get_P_WORK(bs_num):
    P_WORK = np.ones(shape=[1, bs_num])  # 与基站数量有关
    P_WORK[:, :] = const.P_STATIC_WORK_MICRO
    P_WORK[0, 0] = const.P_STATIC_WORK_MACRO
    return P_WORK

def get_P_SLEEP(bs_num):
    P_SLEEP = np.ones(shape=[1, bs_num])
    P_SLEEP[:, :] = const.P_STATIC_SLEEP_MICRO
    P_SLEEP[0, 0] = const.P_STATIC_SLEEP_MACRO
    return P_SLEEP

def get_ONE_BS(bs_num):
    return np.ones(shape=[1, bs_num])

def get_ZERO_BS(bs_num):
    return np.zeros(shape=[1, bs_num])